package com.moli.iov.handle.real.service.impl;

import com.moli.iov.cache.RedisUtil;
import com.moli.iov.contant.RealContant;
import com.moli.iov.handle.real.model.RealTimeReqDto;
import com.moli.iov.handle.real.repositories.RealTimeDao;
import com.moli.iov.handle.real.service.RealTimeInfoService;
import com.moli.iov.protocol.model.dto.realtime.RealTimeInfoDto;
import com.moli.iov.protocol.model.realtime.RealTimeInfo;
import com.moli.iov.protocol.model.realtime.RealTimeInfoReq;
import com.moli.iov.util.JsonUtils;
import com.moli.iov.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @ClassName RealTimeInfoServiceImpl
 * @Description TODO
 * @Author 李伟松
 * @CreateDate 2019-02-26 下午 5:24
 * @UpdateDate 2019-02-26 下午 5:24
 * @Version 1.0
 */
@Slf4j
@Service
public class RealTimeInfoServiceImpl implements RealTimeInfoService {

    private static final String KEY_LOCATIONSTATE = "IOV:PROTOCOL:LOCATIONSTATE";

    private static final String KEY_DYNAMICSTATE = "IOV:PROTOCOL:DYNAMICSTATE";

    private static final String SPLIT = "_";

    @Resource
    RedisUtil redisUtil;

    @Resource
    RealTimeDao realTimeDao;

    @Override
    public List<RealTimeInfo> list(RealTimeReqDto realTimeReqDto) {
        List<RealTimeInfo> realTimeInfos =
                realTimeDao.find(assemblyConditions(realTimeReqDto));
        return realTimeInfos;
    }

    @Override
    public Map<String,RealTimeInfo> map(RealTimeReqDto realTimeReqDto) {
        List<RealTimeInfo> realTimeInfos =
                realTimeDao.find(assemblyConditions(realTimeReqDto));
        if(realTimeInfos!=null && realTimeInfos.size()>0){
            Map<String, RealTimeInfo> map = new HashMap<>();
            for (RealTimeInfo realTimeInfo : realTimeInfos) {
                map.put(realTimeInfo.getVin(),realTimeInfo);
            }
            return map;
        }
        return new HashMap<String, RealTimeInfo>();
    }



    private Query assemblyConditions(RealTimeReqDto realTimeReqDto) {
        Criteria criteria = new Criteria();

        if (StringUtil.isNotBlank(realTimeReqDto.getVin())) {
            criteria.and("vin").is(realTimeReqDto.getVin());
        }
        if(realTimeReqDto.getVins()!=null && realTimeReqDto.getVins().size()>0){
            criteria.and("vin").in(realTimeReqDto.getVins());
        }

        Query query = new Query(criteria);

        log.info("入参：{} 组装条件：{}，", realTimeReqDto, query);
        return query;
    }


    /**
     * @Param: [vinList]
     * @Return: java.util.Map<String   ,   RealTimeInfoDto>
     * @Description 根据车架号集合获取车辆实时信息
     * @Author 李伟松
     * @CreateDate 2019-02-26 下午 5:42
     */
    @Override
    public Map<String, RealTimeInfoDto> getRealTimeInfoDtoMap(List<String> vinList) {

        if(vinList==null || vinList.isEmpty()){
            return null;
        }

        List<String> jsonList = redisUtil.hgetString(RealContant.KEY_MSG_REALTIME, vinList);
        if (jsonList == null || jsonList.isEmpty()) {
            log.error("未查询到实时信息,参数:{}", vinList);
            return null;
        }

        Map<String, RealTimeInfoDto> map = new HashMap<>();

        for (String json : jsonList) {
            RealTimeInfoDto dto = JsonUtils.parse(json, RealTimeInfoDto.class);
            if (dto != null && !StringUtils.isEmpty(dto.getVin())) {
                map.put(dto.getVin(), dto);
            }
        }

        return map;
    }

    /**
     * @Param: [realInfoForCacheMap：存放解析后报文,realInfoOriginalForCacheMap：存放解析前报文,locationStateForCacheMap：存放定位状态]
     * @Return: java.util.Map<java.lang.String   ,   com.moli.iov.protocol.model.dto.realtime.RealTimeInfoDto>
     * @Description 将报文解析后存入缓存
     * @Author 李伟松
     * @CreateDate 2019-02-26 下午 5:42
     */
    @Override
    public void putCache( Map<String, String> locationStateForCacheMap,Map<String, String> dsMap) {

//        if (realInfoForCacheMap != null && !realInfoForCacheMap.isEmpty()) {
//            redisUtil.hset(RealContant.KEY_MSG_REALTIME, realInfoForCacheMap);
//        }
//        if (realInfoOriginalForCacheMap != null && !realInfoOriginalForCacheMap.isEmpty()) {
//            redisUtil.hset(RealContant.KEY_ORIGINAL_REALTIME, realInfoOriginalForCacheMap);
//        }
        if (locationStateForCacheMap != null && !locationStateForCacheMap.isEmpty()) {
            redisUtil.hset(KEY_LOCATIONSTATE, locationStateForCacheMap);
        }
        if (dsMap != null && !dsMap.isEmpty()) {
            redisUtil.hset(KEY_DYNAMICSTATE, dsMap);
        }
    }

    @Override
    public void batchSave(List<RealTimeInfo> list, Set<String> vins) {
        if(list!=null && list.size()>0){
            for (RealTimeInfo realTimeInfo : list) {
                if(realTimeInfo==null || StringUtils.isEmpty(realTimeInfo.getVin())){
                    continue;
                }

                Query query = new Query(Criteria.where("vin").is(realTimeInfo.getVin()));
                Update update = new Update();

                update.set("vin",realTimeInfo.getVin());
                update.set("realTimeInfoReq",realTimeInfo.getRealTimeInfoReq());

                if(realTimeInfo.getLongitude()>0){
                    update.set("longitude",realTimeInfo.getLongitude());
                    update.set("latitude",realTimeInfo.getLatitude());
                    update.set("gpsReportTime",realTimeInfo.getGpsReportTime());
                }

                if(realTimeInfo.getMaxOdo()!=null){
                    update.set("maxOdo",realTimeInfo.getMaxOdo());
                    update.set("maxOdoReportTime",realTimeInfo.getMaxOdoReportTime());
                }

                if(realTimeInfo.getGpsOdo()!=null){
                    update.set("gpsOdo",realTimeInfo.getGpsOdo());
                    update.set("gpsOdoCalcTime",realTimeInfo.getGpsOdoCalcTime());
                }

                if(realTimeInfo.getLastOdoReportTime()!=null){
                    update.set("lastOdoReportTime",realTimeInfo.getLastOdoReportTime());
                }

                if(realTimeInfo.getGpsOdoList()!=null && realTimeInfo.getGpsOdoList().size()>0){
                    update.set("gpsOdoList",realTimeInfo.getGpsOdoList());
                }


                realTimeDao.upsert(query,update);

//                if(vins!=null && vins.contains(realTimeInfo.getVin())){
//                    Query query = new Query(Criteria.where("vin").is(realTimeInfo.getVin()));
//                    Update update = new Update()
//                            .set("vin",realTimeInfo.getVin())
//                            .set("realTimeInfoReq",realTimeInfo.getRealTimeInfoReq());
//                    realTimeDao.upsert(query,update);
//                }else{
//                    realTimeDao.save(realTimeInfo);
//                }
            }
        }
    }
}
